package com.src.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TimeZone;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JMenuBar;
import javax.swing.table.DefaultTableCellRenderer;

import run.dbConnection;

import com.src.calendarItem.Event;
import java.awt.Toolkit;

public class Mainframe extends JFrame {

	private static final long serialVersionUID = 1L;
	// Tabbed Pane View
	private JTabbedPane jContentPane = null;
	private JPanel jMonthlyPane = null;
	private JPanel jWeeklyPane = null;
	private JPanel eventsArea = null;
	private JScrollPane  evArea =null;
	private JButton forward_mo = null;
	private JButton backward_mo = null;
	private JLabel cmonth = null;
	private JLabel cyear = null;
	private JMenu menu_event;
	private JMenu menu_help;
	private Calendar cal;
	private JLabel daysofmonth[];
	private JTable tableofweek;
	private String[][] daysofweek;
	private Vector<Event> events;

	final private String[]  months = {"January","February","March","April","May",
			"June","July","August","September","October","November","December"};
	
	final public String[] weekdays = {"","Sunday","Monday","Tuesday","Wednesday",
			"Thursday","Friday","Saturday"};
	
	
	public HashMap<Integer,Event> allEvents;
	public HashMap<Integer, String> eventCells;
	int CMONTH;
	int CYEAR;
	int CDAY;
	private JMenuBar jJMenuBar = null;
	private Event currentev;
	private dbConnection database;
	private ImageIcon selectedicon = new ImageIcon("./src/icon/select.png");
        private Mainframe frame;
	/**
	 * This is the default constructor
	 */
	public Mainframe() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		
		
		cal = new GregorianCalendar(TimeZone.getTimeZone("EDT"));
		cal = Calendar.getInstance();
		
		CMONTH = cal.get(Calendar.MONTH);
		CYEAR = cal.get(Calendar.YEAR);
		CDAY = cal.get(Calendar.DAY_OF_MONTH);
		
		daysofmonth= new JLabel[42];
		
		database = new dbConnection();
		allEvents = database.getAllEvents();
		
		this.setSize(700, 400);
		this.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/icon/001_44.png")));
		this.setJMenuBar(getJJMenuBar());
		this.setContentPane(getJContentPane());
		this.setTitle("jCal - by Jeff");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationRelativeTo(null);
		//this.setResizable(false);
                this.frame = this;

	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JTabbedPane getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JTabbedPane();
			jContentPane.addTab("Month",null,getJMonthlyPane(),"This is the Monthly View of Calendar");
			jContentPane.addTab("Week",null,getJWeeklyPane(),"This is the Weekly View of Calendar");
		}
		return jContentPane;
	}

	
	
	private JPanel getJMonthlyPane() {
		if(jMonthlyPane == null) {
			jMonthlyPane = new JPanel(new BorderLayout(30,10));
		
			//construct the control bar
			// << Month >>
			JPanel controlPane = new JPanel(new GridLayout(1,3,10,10));
			backward_mo = new JButton("<<");		
			cmonth = new JLabel(months[CMONTH],JLabel.TRAILING);
			cyear = new JLabel(Integer.toString(CYEAR),JLabel.LEADING);
			forward_mo = new JButton(">>");
			controlPane.add(backward_mo);
			controlPane.add(cmonth);
			controlPane.add(cyear);
			controlPane.add(forward_mo);
			
			backward_mo.addActionListener(new java.awt.event.ActionListener(){
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					CMONTH--;
					if(CMONTH<0)
					{
						CMONTH = 11 ; CYEAR--;
					}
					do_daysofmonth(CMONTH,CYEAR,daysofmonth);
					
					cmonth.setText(months[CMONTH]);
					cyear.setText(String.valueOf(CYEAR));
				}
			});
			
			forward_mo.addActionListener(new java.awt.event.ActionListener(){
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					CMONTH++;
					if(CMONTH>11)
					{
						CMONTH = 0 ; CYEAR++;
					}
					do_daysofmonth(CMONTH,CYEAR,daysofmonth);
					
					cmonth.setText(months[CMONTH]);
					cyear.setText(String.valueOf(CYEAR));
				}
			});
			
			jMonthlyPane.add(controlPane,BorderLayout.NORTH);
			
			JPanel monthPane = new JPanel(new GridLayout(7,6,10,20));
			
			monthPane.add(new JLabel("Sunday",JLabel.TRAILING));
			monthPane.add(new JLabel("Monday",JLabel.TRAILING));
			monthPane.add(new JLabel("Tuesday",JLabel.TRAILING));
			monthPane.add(new JLabel("Wednesday",JLabel.TRAILING));
			monthPane.add(new JLabel("Thursday",JLabel.TRAILING));
			monthPane.add(new JLabel("Friday",JLabel.TRAILING));
			monthPane.add(new JLabel("Saturday",JLabel.TRAILING));
			
			for(int i=0; i<42; i++)
			{
				daysofmonth[i] = new JLabel("",JLabel.TRAILING);
				daysofmonth[i].setSize(30, 30);
				monthPane.add(daysofmonth[i]);;
			}
			
			do_daysofmonth(CMONTH,CYEAR,daysofmonth);
			monthPane.setOpaque(false);
			jMonthlyPane.add(monthPane,BorderLayout.CENTER);	

			setEventPane(getToday());
			jMonthlyPane.add(evArea, BorderLayout.SOUTH);
		}
		
		return jMonthlyPane;
	}

	private void setEventPane(String date) {
	
		if(eventsArea!= null)
		{jMonthlyPane.remove(evArea);}
		//evArea = new JScrollPane(eventsArea);	
		events = database.getEventofDate(date);
		int lines = events.size();
		eventsArea = new JPanel(new GridLayout(0,2,1,2));
		Iterator it_events = events.iterator();
		if(events!=null&&(!events.isEmpty()))
		{	int eventid = 0;
			while(it_events.hasNext())
			{	
				Event event = (Event) it_events.next();
				this.currentev = event;
				eventsArea.add(new JTextArea(event.toShortView()));
				JButton evdetail = new JButton(">>");
				evdetail.setActionCommand(String.valueOf(eventid++));
				evdetail.addActionListener(new java.awt.event.ActionListener(){
					
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					int evid = Integer.valueOf(e.getActionCommand());
					ViewEvent view = new ViewEvent(events.get(evid),frame);
					view.setVisible(true);
					
				}});
				eventsArea.add(evdetail);
			}	
		}
		else
		{
			eventsArea.add(new JTextArea("No Event"));
		}

		evArea = new JScrollPane(eventsArea);
		jMonthlyPane.add(evArea,BorderLayout.SOUTH);
	}
	
	private JPanel getJWeeklyPane() {
		if(jWeeklyPane == null) {
			jWeeklyPane = new JPanel();
			
			daysofweek = new String[24][8];
			
			Calendar setcal = new GregorianCalendar();
			
			setcal.set(CYEAR,CMONTH,CDAY);
			int today = setcal.get(Calendar.DAY_OF_WEEK)-1;
			int start = CDAY - today;
			int over = 1;
			for(int i = 1 ;i<weekdays.length;i++)
			{
                                // set the date view after Day of Week, like Monday 1/9
				weekdays[i]= weekdays[i]+((start<=setcal.getActualMaximum(Calendar.DAY_OF_MONTH))?((start++)+"/"+(CMONTH+1)):((over++)+"/"+((CMONTH<12)?CMONTH+1:"1")));
			}
			
//			for(String weekday:weekdays)
//			{
//				weekday = weekday+String.valueOf(start++)+"/"+String.valueOf(CMONTH);
//			}
			tableofweek = new JTable(daysofweek,weekdays);
			tableofweek.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
			tableofweek.setPreferredSize(null);
			tableofweek.setPreferredScrollableViewportSize(new Dimension(650,280));
			tableofweek.setCellSelectionEnabled(true);
			tableofweek.setOpaque(false);
			tableofweek.setDefaultRenderer(Object.class,new AttributiveCellRenderer());
			
			JScrollPane weekPane  = new JScrollPane(tableofweek);
			eventCells = new HashMap<Integer,String>();
			do_daysofweek(CDAY,CMONTH,daysofweek);
			jWeeklyPane.add(weekPane);
			
		}
		return jWeeklyPane;
	}
	
	public void do_daysofweek(int day, int mo, String[][] days)
	{
		for (int i=0;i<24;i++)
		{
			if(i<=12)
				days[i][0] = String.valueOf(i)+"am";
			else
				days[i][0] = String.valueOf(i-12)+"pm";
		}
		
		//put in the event in days
		//get all the week events
		//
		Calendar setcal = new GregorianCalendar();
		
		setcal.set(CYEAR,CMONTH,CDAY);
		int today = setcal.get(Calendar.DAY_OF_WEEK)-1;
		int start = CDAY - today;
		for(int i = start; i< start+7; i++)
		{
			Vector<Event> evs = database.getEventofDate(getDate(CYEAR,CMONTH,i));
			// put event on time table
			// get the event of current day and put it into the time table--get cell id(height 24, weight 8(start from 1))
			for(Event ev: evs)
			{
				String st = ev.getStartTime();
				String ed = ev.getEndTime();
				//need a method to return the cells
				int[] cells = getTimeCell(st,ed);
				//change the cell behavior
				for(int cell:cells)
				{
					tableofweek.setValueAt(ev.getSummary(), cell, (i-start+1));
					Integer eventkey = Integer.valueOf(String.valueOf(cell)+String.valueOf(i-start+1));
					eventCells.put(eventkey,ev.getSummary());
				}	
			}
		}
		
		
		tableofweek.repaint();
	}
	
	//only handle the event occur during one day
	private int[] getTimeCell(String st, String ed)
	{
		
		
		int start = Integer.valueOf(st.substring(0, 2));
		int end = Integer.valueOf(ed.substring(0,2));
		
		int[] cells = new int[end-start+1];
		int count = start;
		for(int i = 0; i<=(end-start);i++)
		{
			cells[i] = count++;
		}
		return cells;
		
	}
	
	public void do_daysofmonth(int mo, int yr, JLabel todo[])
	{
		Calendar setcal = new GregorianCalendar();
		setcal.set(yr,mo,1);
		
		int startday = setcal.get(Calendar.DAY_OF_WEEK)-1;
		int stopday = setcal.getActualMaximum(Calendar.DAY_OF_MONTH);
		for(int i=0; i<startday;i++)
		{
			todo[i].setText("");	
		}
		for (int i = startday; i< startday+stopday;i++)
		{
			int day = i - startday +1;
			
			if(database.hasEvent(getDate(yr,mo,day)))
			{
				//no something to show it has event
				todo[i].setIcon(selectedicon);
				todo[i].setText(String.valueOf(day));
			}
			else
			{
                                todo[i].setIcon(null);
				todo[i].setText(String.valueOf(day));
			}
			
			todo[i].addMouseListener(new MouseAdapter()
			{
				public void mouseClicked(MouseEvent me)
					{
						for(JLabel label:daysofmonth)
						{
							label.setOpaque(false);
						}
						JLabel cur = (JLabel)me.getSource();
						// change the event view
						
						cur.setOpaque(true);
						cur.setBackground(Color.green);
						
						setEventPane(getDate(CYEAR,CMONTH,Integer.valueOf(cur.getText())));
						repaint(0);
					}
			});

			
		}
		for (int i=startday+stopday;i<42;i++)
		{
			todo[i].setText("");
		}
		
	}

	/**
	 * This method initializes jJMenuBar	
	 * 	
	 * @return javax.swing.JMenuBar	
	 */
	private JMenuBar getJJMenuBar() {
		if (jJMenuBar == null) {
			jJMenuBar = new JMenuBar();
			
			menu_event = new JMenu("Event");
			menu_event.setMnemonic(KeyEvent.VK_E);
						
			
			JMenuItem menuItem_addevent = new JMenuItem("Add Event");
			menuItem_addevent.setMnemonic(KeyEvent.VK_A);
			menuItem_addevent.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
					AddEvent addevent = new AddEvent(frame);
					addevent.setVisible(true);
					
				}
			});
			
			
			menu_event.add(menuItem_addevent);
			

			menu_help = new JMenu("Help");
			menu_help.setMnemonic(KeyEvent.VK_H);
			
			JMenuItem menuItem_about = new JMenuItem("About");
			menuItem_about.setMnemonic(KeyEvent.VK_A);
			menuItem_about.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e){
					
					JOptionPane.showMessageDialog(null,"jCal - Java Calendar Application\nDeveloped by Jeff Zhao\n" +
							"Email:jeffzhao415@gmail.com\n"+"Sep/20/2009","About", JOptionPane.PLAIN_MESSAGE); 
				}
			});
			
			menu_help.add(menuItem_about);
			
			jJMenuBar.add(menu_event);
			jJMenuBar.add(menu_help);
		}
		return jJMenuBar;
	}
	
	public String getToday()
	{
		int imonth = CMONTH+1;
		String month = (imonth>=10)? String.valueOf(imonth):("0"+String.valueOf(imonth));
		String sday = (CDAY>=10)?String.valueOf(CDAY):("0"+String.valueOf(CDAY));
		return String.valueOf(CYEAR)+month+sday;
	}

	public String getDate(int year, int month, int day)
	{
		int imonth = month+1;
		String mon = (imonth>=10)? String.valueOf(imonth):("0"+String.valueOf(imonth));
		String sday = (day>=10)?String.valueOf(day):("0"+String.valueOf(day));
		return String.valueOf(year)+mon+sday;
	}
	
	public class AttributiveCellRenderer extends DefaultTableCellRenderer
	{
		public AttributiveCellRenderer()
		{
			setOpaque(true);
		}
		
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row, int column)
		{
			//set the event cell background to blue color
			Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			Integer cellKey = Integer.valueOf(String.valueOf(row)+String.valueOf(column));
			if(eventCells.containsKey(cellKey))
			{
				cell.setBackground(Color.GREEN);
				tableofweek.setValueAt(eventCells.get(cellKey), row, column);
			}
			else
			{
				cell.setBackground(null);
			}
			return this;
		}
	}

        public void refresh()
        {
            allEvents = database.getAllEvents();
            jContentPane.revalidate();
            tableofweek.revalidate();
            setEventPane(getToday());
        }
}
